Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(query-builder): support for nested queries and other improvements #14647

Open
wants to merge 264 commits into
base: master
Choose a base branch
from

Conversation

igdmdimitrov
Copy link
Contributor

@igdmdimitrov igdmdimitrov commented Aug 19, 2024

Closes #14642
Closes #14979

Additional information (check all that apply):

  • Bug fix
  • New functionality
  • Documentation
  • Demos
  • CI/CD

Checklist:

  • All relevant tags have been applied to this PR
  • This PR includes unit tests covering all the new code (test guidelines)
  • This PR includes API docs for newly added methods/properties (api docs guidelines)
  • This PR includes feature/README.MD updates for the feature docs
  • This PR includes general feature table updates in the root README.MD
  • This PR includes CHANGELOG.MD updates for newly added functionality
  • This PR contains breaking changes
  • This PR includes ng update migrations for the breaking changes (migrations guidelines)
  • This PR includes behavioral changes and the feature specification has been updated with them

@igdmdimitrov igdmdimitrov added the 🛠️ status: in-development Issues and PRs with active development on them label Aug 19, 2024
@gedinakova

This comment was marked as outdated.

@gedinakova

This comment was marked as outdated.

@gedinakova

This comment was marked as outdated.

@gedinakova

This comment was marked as outdated.

@gedinakova

This comment was marked as outdated.

@Otixa

This comment was marked as outdated.

@teodosiah

This comment was marked as outdated.

@teodosiah
Copy link
Contributor

  1. Add query builder without initially set expression tree:
    <igx-query-builder #queryBuilder [entities]="this.entities"></igx-query-builder>

The '+' icons in the add "'and'/'or' group" buttons are not displayed.

Suggestion: move the registerSVGIcons method to the query-builder.component.ts and call it on initial loading because when there is no expression tree a query-builder-tree is not created and the method is not called

@teodosiah
Copy link
Contributor

  1. Add query builder without initially set expression tree
  2. Add new group:
    image
  3. Commit it:
    image
  4. Delete the group
  5. Click on some of the add new group buttons
    The selected entity is the same as the previously deleted:
    image

Should we keep the previous selection?

@teodosiah
Copy link
Contributor

  1. Add query builder without initially set expression tree
  2. Click on some of the add new group buttons (all inputs are empty)
  3. Click on the entity select

Result:
The Confirmation dialog is shown.

Should we open the dialog when initially setting (not changing) the entity?

@teodosiah
Copy link
Contributor

  1. Start editing some query
    The conditions drop-downs are placed in the igx-query-builder__outlet, however the entity and fields drop-downs are outside:
    qb_overlay
    This could be the reason for the following scenario:
    image

@@ -15,6 +16,8 @@ const QueryBuilderResourceStringsIT_: ExpandRequire<IQueryBuilderResourceStrings
igx_query_builder_filter_notEmpty: 'Non vuoto',
igx_query_builder_filter_null: 'Null',
igx_query_builder_filter_notNull: 'Non null',
igx_query_builder_filter_in: 'In',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Translation missing

@@ -15,6 +16,8 @@ const QueryBuilderResourceStringsKO_: ExpandRequire<IQueryBuilderResourceStrings
igx_query_builder_filter_notEmpty: '비우지 않음',
igx_query_builder_filter_null: 'Null',
igx_query_builder_filter_notNull: 'Not Null',
igx_query_builder_filter_in: 'In',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Translation missing

this.setDragCursor('grab');

//TODO z-index is set, but ghost still not visible in Dialog
if(this.dragGhostElement.style) this.dragGhostElement.style.zIndex = "9999";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DRAG GHOST NOT VISIBLE IN DIALOG

Event after setting the z-index of the drag ghost to 9999, it's still not visible over the dialog.
As you can see, the ghost is rendered as last child of the body, outside app-root and overlay and we don't have control over this:
image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems that the overlay is with z-index 10005.
That's why 9999was not working. 10006 is...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ivanvpetrov Why can't move the ghost element inside the query builder?
Adding a z-index to the ghost element is not a viable solution, as any future changes to the z-index of the overlay could result in unintended regressions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have almost no control over the drag ghost. It's part of the igx-chip's drag directive and we use it out of the box.
I've looked at other examples along the documentation, the drag ghost is always a sibling of the body, outside any enclosure.

@sbayreva
Copy link

Indigo
There is some inconsistency with the colors for the footer:

Screenshot 2025-02-10 at 17 38 11
The background + the background of the footer should be grays 50

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't these be 19.1 migrations?

@@ -131,7 +131,7 @@ export class IgxAdvancedFilteringDialogComponent implements AfterViewInit, OnDes
eventArgs.stopPropagation();
const key = eventArgs.key;
if (this.queryBuilder.isContextMenuVisible && (key === this.platform.KEYMAP.ESCAPE)) {
this.queryBuilder.clearSelection();

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like an empty if block?

queryBuilder.expressionTree = QueryBuilderFunctions.generateExpressionTree();
fix.detectChanges();
tick(100);
fix.detectChanges();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally speaking we are trying to avoid arbitrarily timed ticks

Also

      fix.detectChanges();
      tick(100);
      fix.detectChanges();

This is a doom sandwich :) Why is it needed?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the changelog, these are not the only changes that the ReadMe should receive

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably not the only file that has these but I notice quite a lot of == in conditions. As part of the best practices we try to employ we use == only when entirely intentional as it's erroneous in JS.

e.g. you have::

this._lastFocusedChipIndex == undefined ? ...

which actually is true if lastFocusedChipIndex is null. Unless this is intentional just use === as it makes the file more easy to understand on the fly as maintainers don't have to think if you intended for the == or not.


public onReturnFieldSelectChanging(event: IComboSelectionChangingEventArgs | ISelectionEventArgs) {
let newSelection = [];
if (event.newSelection instanceof Array) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not the biggest fan of instanceof when it can be avoided. It probably wouldn't matter in this case but have in mind that it can be erroneous . As there is Array.isArray method, you don't have to use it here.

return groupItem;
}

for (const expr of expressionTree.filteringOperands) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for of loops look cool but they are a lot ot slower than traditional for i; i< array.length . Sometimes traditional is better :)


//Get the dragged ghost as a HTMLElement
private get dragGhostElement(): HTMLElement {
return (document.querySelector('.igx-chip__ghost[ghostclass="igx-chip__ghost"]') as HTMLElement);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you checked what happens if you have two QBs on the page?


//Create the drop ghost node based on the base chip that's been dragged
private createDropGhost(keyboardMode?: boolean) {
const dragCopy = this.sourceElement.cloneNode(true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is DOM magic galore. Isn't there a way to template the ghost instead?

private renderDropGhostChip(appendToElement: HTMLElement, appendUnder: boolean, keyboardMode?: boolean): void {
const dragCopy = this.createDropGhost(keyboardMode);

//Append the ghost
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above. We want to minimize DOM manipulation in Angulara as much as possible. I am not going to stop the pr from being merged because of this but double check if it's possible to tempalte this please.

@ig-georgeA
Copy link

Keyboard interactions via tab and shift+tab stop working.
Steps:

  1. use the tab key to focus the drag indicator
  2. use up/down arrow to rearrange conditions
  3. hit tab or shift+tab to change focus to a different element
  4. Unable to focus
image

@ivanvpetrov
Copy link
Contributor

Keyboard interactions via tab and shift+tab stop working. Steps:

  1. use the tab key to focus the drag indicator
  2. use up/down arrow to rearrange conditions
  3. hit tab or shift+tab to change focus to a different element
  4. Unable to focus
image

This behavior is made intentionally. Once you start the drag&drop procedure (hance hitting up/down) the only way to exit this state is confirming(Enter) or canceling(Esc). That's why Tabs is inhibited.
If not inhibited, you would loose focus and leave the drag&drop in unfinished state.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Query Builder: Update theme to match latest design Query Builder component update